﻿using System.Collections.Generic;
using System.Diagnostics.Contracts;
using System.Linq.Expressions;
using System.Reactive.Concurrency;
using System.Reactive.Subjects;

namespace System.Reactive.Linq
{
	public static partial class Qbservable
	{
		public static IQbservable<TResult> ManySelect<TSource, TResult>(this IQbservable<TSource> source, Expression<Func<IObservable<TSource>, TResult>> selector)
		{
			Contract.Requires(source != null, null, "source != null");
			Contract.Requires(selector != null, null, "selector != null");
			Contract.Ensures(Contract.Result<IQbservable<TResult>>() != null, null, "Contract.Result<IQbservable<TResult>>() != null");
			return null;
		}

		public static IQbservable<TResult> ManySelect<TSource, TResult>(this IQbservable<TSource> source, Expression<Func<IObservable<TSource>, TResult>> selector, IScheduler scheduler)
		{
			Contract.Requires(source != null, null, "source != null");
			Contract.Requires(selector != null, null, "selector != null");
			Contract.Requires(scheduler != null, null, "scheduler != null");
			Contract.Ensures(Contract.Result<IQbservable<TResult>>() != null, null, "Contract.Result<IQbservable<TResult>>() != null");
			return null;
		}

		public static IQbservable<Notification<TSource>> Materialize<TSource>(this IQbservable<TSource> source)
		{
			Contract.Requires(source != null, null, "source != null");
			Contract.Ensures(Contract.Result<IQbservable<Notification<TSource>>>() != null, null, "Contract.Result<IQbservable<Notification<TSource>>>() != null");
			return null;
		}

		public static IQbservable<decimal?> Max(this IQbservable<decimal?> source)
		{
			Contract.Requires(source != null, null, "source != null");
			Contract.Ensures(Contract.Result<IQbservable<decimal?>>() != null, null, "Contract.Result<IQbservable<decimal?>>() != null");
			return null;
		}

		public static IQbservable<decimal> Max(this IQbservable<decimal> source)
		{
			Contract.Requires(source != null, null, "source != null");
			Contract.Ensures(Contract.Result<IQbservable<decimal>>() != null, null, "Contract.Result<IQbservable<decimal>>() != null");
			return null;
		}

		public static IQbservable<double?> Max(this IQbservable<double?> source)
		{
			Contract.Requires(source != null, null, "source != null");
			Contract.Ensures(Contract.Result<IQbservable<double?>>() != null, null, "Contract.Result<IQbservable<double?>>() != null");
			return null;
		}

		public static IQbservable<double> Max(this IQbservable<double> source)
		{
			Contract.Requires(source != null, null, "source != null");
			Contract.Ensures(Contract.Result<IQbservable<double>>() != null, null, "Contract.Result<IQbservable<double>>() != null");
			return null;
		}

		public static IQbservable<float?> Max(this IQbservable<float?> source)
		{
			Contract.Requires(source != null, null, "source != null");
			Contract.Ensures(Contract.Result<IQbservable<float?>>() != null, null, "Contract.Result<IQbservable<float?>>() != null");
			return null;
		}

		public static IQbservable<float> Max(this IQbservable<float> source)
		{
			Contract.Requires(source != null, null, "source != null");
			Contract.Ensures(Contract.Result<IQbservable<float>>() != null, null, "Contract.Result<IQbservable<float>>() != null");
			return null;
		}

		public static IQbservable<int?> Max(this IQbservable<int?> source)
		{
			Contract.Requires(source != null, null, "source != null");
			Contract.Ensures(Contract.Result<IQbservable<int?>>() != null, null, "Contract.Result<IQbservable<int?>>() != null");
			return null;
		}

		public static IQbservable<int> Max(this IQbservable<int> source)
		{
			Contract.Requires(source != null, null, "source != null");
			Contract.Ensures(Contract.Result<IQbservable<int>>() != null, null, "Contract.Result<IQbservable<int>>() != null");
			return null;
		}

		public static IQbservable<long?> Max(this IQbservable<long?> source)
		{
			Contract.Requires(source != null, null, "source != null");
			Contract.Ensures(Contract.Result<IQbservable<long?>>() != null, null, "Contract.Result<IQbservable<long?>>() != null");
			return null;
		}

		public static IQbservable<long> Max(this IQbservable<long> source)
		{
			Contract.Requires(source != null, null, "source != null");
			Contract.Ensures(Contract.Result<IQbservable<long>>() != null, null, "Contract.Result<IQbservable<long>>() != null");
			return null;
		}

		public static IQbservable<TSource> Max<TSource>(this IQbservable<TSource> source)
		{
			Contract.Requires(source != null, null, "source != null");
			Contract.Ensures(Contract.Result<IQbservable<TSource>>() != null, null, "Contract.Result<IQbservable<TSource>>() != null");
			return null;
		}

		public static IQbservable<TSource> Max<TSource>(this IQbservable<TSource> source, IComparer<TSource> comparer)
		{
			Contract.Requires(source != null, null, "source != null");
			Contract.Requires(comparer != null, null, "comparer != null");
			Contract.Ensures(Contract.Result<IQbservable<TSource>>() != null, null, "Contract.Result<IQbservable<TSource>>() != null");
			return null;
		}

		public static IQbservable<IList<TSource>> MaxBy<TSource, TKey>(this IQbservable<TSource> source, Expression<Func<TSource, TKey>> keySelector)
		{
			Contract.Requires(source != null, null, "source != null");
			Contract.Requires(keySelector != null, null, "keySelector != null");
			Contract.Ensures(Contract.Result<IQbservable<IList<TSource>>>() != null, null, "Contract.Result<IQbservable<IList<TSource>>>() != null");
			return null;
		}

		public static IQbservable<IList<TSource>> MaxBy<TSource, TKey>(this IQbservable<TSource> source, Expression<Func<TSource, TKey>> keySelector, IComparer<TKey> comparer)
		{
			Contract.Requires(source != null, null, "source != null");
			Contract.Requires(keySelector != null, null, "keySelector != null");
			Contract.Requires(comparer != null, null, "comparer != null");
			Contract.Ensures(Contract.Result<IQbservable<IList<TSource>>>() != null, null, "Contract.Result<IQbservable<IList<TSource>>>() != null");
			return null;
		}

		public static IQbservable<TSource> Merge<TSource>(this IQbservableProvider provider, params IObservable<TSource>[] sources)
		{
			Contract.Requires(provider != null, null, "provider != null");
			Contract.Requires(sources != null, null, "sources != null");
			//Contract.Requires(Contract.ForAll(sources, observable => observable != null), null, "Contract.ForAll(sources, observable => observable != null)");
			Contract.Ensures(Contract.Result<IQbservable<TSource>>() != null, null, "Contract.Result<IQbservable<TSource>>() != null");
			return null;
		}

		public static IQbservable<TSource> Merge<TSource>(this IQbservableProvider provider, IEnumerable<IObservable<TSource>> sources)
		{
			Contract.Requires(provider != null, null, "provider != null");
			Contract.Requires(sources != null, null, "sources != null");
			//Contract.Requires(Contract.ForAll(sources, observable => observable != null), null, "Contract.ForAll(sources, observable => observable != null)");
			Contract.Ensures(Contract.Result<IQbservable<TSource>>() != null, null, "Contract.Result<IQbservable<TSource>>() != null");
			return null;
		}

		public static IQbservable<TSource> Merge<TSource>(this IQbservable<IObservable<TSource>> sources)
		{
			Contract.Requires(sources != null, null, "sources != null");
			Contract.Ensures(Contract.Result<IQbservable<TSource>>() != null, null, "Contract.Result<IQbservable<TSource>>() != null");
			return null;
		}

		public static IQbservable<TSource> Merge<TSource>(this IQbservableProvider provider, IScheduler scheduler, params IObservable<TSource>[] sources)
		{
			Contract.Requires(provider != null, null, "provider != null");
			Contract.Requires(scheduler != null, null, "scheduler != null");
			Contract.Requires(sources != null, null, "sources != null");
			//Contract.Requires(Contract.ForAll(sources, observable => observable != null), null, "Contract.ForAll(sources, observable => observable != null)");
			Contract.Ensures(Contract.Result<IQbservable<TSource>>() != null, null, "Contract.Result<IQbservable<TSource>>() != null");
			return null;
		}

		public static IQbservable<TSource> Merge<TSource>(this IQbservableProvider provider, IEnumerable<IObservable<TSource>> sources, int maxConcurrent)
		{
			Contract.Requires(provider != null, null, "provider != null");
			Contract.Requires(sources != null, null, "sources != null");
			//Contract.Requires(Contract.ForAll(sources, observable => observable != null), null, "Contract.ForAll(sources, observable => observable != null)");
			Contract.Ensures(Contract.Result<IQbservable<TSource>>() != null, null, "Contract.Result<IQbservable<TSource>>() != null");
			return null;
		}

		public static IQbservable<TSource> Merge<TSource>(this IQbservableProvider provider, IEnumerable<IObservable<TSource>> sources, IScheduler scheduler)
		{
			Contract.Requires(provider != null, null, "provider != null");
			Contract.Requires(sources != null, null, "sources != null");
			//Contract.Requires(Contract.ForAll(sources, observable => observable != null), null, "Contract.ForAll(sources, observable => observable != null)");
			Contract.Requires(scheduler != null, null, "scheduler != null");
			Contract.Ensures(Contract.Result<IQbservable<TSource>>() != null, null, "Contract.Result<IQbservable<TSource>>() != null");
			return null;
		}

		public static IQbservable<TSource> Merge<TSource>(this IQbservable<IObservable<TSource>> sources, int maxConcurrent)
		{
			Contract.Requires(sources != null, null, "sources != null");
			Contract.Ensures(Contract.Result<IQbservable<TSource>>() != null, null, "Contract.Result<IQbservable<TSource>>() != null");
			return null;
		}

		public static IQbservable<TSource> Merge<TSource>(this IQbservable<TSource> first, IObservable<TSource> second)
		{
			Contract.Requires(first != null, null, "first != null");
			Contract.Requires(second != null, null, "second != null");
			Contract.Ensures(Contract.Result<IQbservable<TSource>>() != null, null, "Contract.Result<IQbservable<TSource>>() != null");
			return null;
		}

		public static IQbservable<TSource> Merge<TSource>(this IQbservableProvider provider, IEnumerable<IObservable<TSource>> sources, int maxConcurrent, IScheduler scheduler)
		{
			Contract.Requires(provider != null, null, "provider != null");
			Contract.Requires(sources != null, null, "sources != null");
			//Contract.Requires(Contract.ForAll(sources, observable => observable != null), null, "Contract.ForAll(sources, observable => observable != null)");
			Contract.Requires(scheduler != null, null, "scheduler != null");
			Contract.Ensures(Contract.Result<IQbservable<TSource>>() != null, null, "Contract.Result<IQbservable<TSource>>() != null");
			return null;
		}

		public static IQbservable<TSource> Merge<TSource>(this IQbservable<TSource> first, IObservable<TSource> second, IScheduler scheduler)
		{
			Contract.Requires(first != null, null, "first != null");
			Contract.Requires(second != null, null, "second != null");
			Contract.Requires(scheduler != null, null, "scheduler != null");
			Contract.Ensures(Contract.Result<IQbservable<TSource>>() != null, null, "Contract.Result<IQbservable<TSource>>() != null");
			return null;
		}

		public static IQbservable<decimal?> Min(this IQbservable<decimal?> source)
		{
			Contract.Requires(source != null, null, "source != null");
			Contract.Ensures(Contract.Result<IQbservable<decimal?>>() != null, null, "Contract.Result<IQbservable<decimal?>>() != null");
			return null;
		}

		public static IQbservable<decimal> Min(this IQbservable<decimal> source)
		{
			Contract.Requires(source != null, null, "source != null");
			Contract.Ensures(Contract.Result<IQbservable<decimal>>() != null, null, "Contract.Result<IQbservable<decimal>>() != null");
			return null;
		}

		public static IQbservable<double?> Min(this IQbservable<double?> source)
		{
			Contract.Requires(source != null, null, "source != null");
			Contract.Ensures(Contract.Result<IQbservable<double?>>() != null, null, "Contract.Result<IQbservable<double?>>() != null");
			return null;
		}

		public static IQbservable<double> Min(this IQbservable<double> source)
		{
			Contract.Requires(source != null, null, "source != null");
			Contract.Ensures(Contract.Result<IQbservable<double>>() != null, null, "Contract.Result<IQbservable<double>>() != null");
			return null;
		}

		public static IQbservable<float?> Min(this IQbservable<float?> source)
		{
			Contract.Requires(source != null, null, "source != null");
			Contract.Ensures(Contract.Result<IQbservable<float?>>() != null, null, "Contract.Result<IQbservable<float?>>() != null");
			return null;
		}

		public static IQbservable<float> Min(this IQbservable<float> source)
		{
			Contract.Requires(source != null, null, "source != null");
			Contract.Ensures(Contract.Result<IQbservable<float>>() != null, null, "Contract.Result<IQbservable<float>>() != null");
			return null;
		}

		public static IQbservable<int?> Min(this IQbservable<int?> source)
		{
			Contract.Requires(source != null, null, "source != null");
			Contract.Ensures(Contract.Result<IQbservable<int?>>() != null, null, "Contract.Result<IQbservable<int?>>() != null");
			return null;
		}

		public static IQbservable<int> Min(this IQbservable<int> source)
		{
			Contract.Requires(source != null, null, "source != null");
			Contract.Ensures(Contract.Result<IQbservable<int>>() != null, null, "Contract.Result<IQbservable<int>>() != null");
			return null;
		}

		public static IQbservable<long?> Min(this IQbservable<long?> source)
		{
			Contract.Requires(source != null, null, "source != null");
			Contract.Ensures(Contract.Result<IQbservable<long?>>() != null, null, "Contract.Result<IQbservable<long?>>() != null");
			return null;
		}

		public static IQbservable<long> Min(this IQbservable<long> source)
		{
			Contract.Requires(source != null, null, "source != null");
			Contract.Ensures(Contract.Result<IQbservable<long>>() != null, null, "Contract.Result<IQbservable<long>>() != null");
			return null;
		}

		public static IQbservable<TSource> Min<TSource>(this IQbservable<TSource> source)
		{
			Contract.Requires(source != null, null, "source != null");
			Contract.Ensures(Contract.Result<IQbservable<TSource>>() != null, null, "Contract.Result<IQbservable<TSource>>() != null");
			return null;
		}

		public static IQbservable<TSource> Min<TSource>(this IQbservable<TSource> source, IComparer<TSource> comparer)
		{
			Contract.Requires(source != null, null, "source != null");
			Contract.Requires(comparer != null, null, "comparer != null");
			Contract.Ensures(Contract.Result<IQbservable<TSource>>() != null, null, "Contract.Result<IQbservable<TSource>>() != null");
			return null;
		}

		public static IQbservable<IList<TSource>> MinBy<TSource, TKey>(this IQbservable<TSource> source, Expression<Func<TSource, TKey>> keySelector)
		{
			Contract.Requires(source != null, null, "source != null");
			Contract.Requires(keySelector != null, null, "keySelector != null");
			Contract.Ensures(Contract.Result<IQbservable<IList<TSource>>>() != null, null, "Contract.Result<IQbservable<IList<TSource>>>() != null");
			return null;
		}

		public static IQbservable<IList<TSource>> MinBy<TSource, TKey>(this IQbservable<TSource> source, Expression<Func<TSource, TKey>> keySelector, IComparer<TKey> comparer)
		{
			Contract.Requires(source != null, null, "source != null");
			Contract.Requires(keySelector != null, null, "keySelector != null");
			Contract.Requires(comparer != null, null, "comparer != null");
			Contract.Ensures(Contract.Result<IQbservable<IList<TSource>>>() != null, null, "Contract.Result<IQbservable<IList<TSource>>>() != null");
			return null;
		}

		public static IEnumerable<TSource> MostRecent<TSource>(this IQbservable<TSource> source, TSource initialValue)
		{
			Contract.Requires(source != null, null, "source != null");
			Contract.Ensures(Contract.Result<IEnumerable<TSource>>() != null, null, "Contract.Result<IEnumerable<TSource>>() != null");
			return null;
		}

		public static IQbservable<TResult> Multicast<TSource, TIntermediate, TResult>(this IQbservable<TSource> source, Expression<Func<ISubject<TSource, TIntermediate>>> subjectSelector, Expression<Func<IObservable<TIntermediate>, IObservable<TResult>>> selector)
		{
			Contract.Requires(source != null, null, "source != null");
			Contract.Requires(subjectSelector != null, null, "subjectSelector != null");
			Contract.Requires(selector != null, null, "selector != null");
			Contract.Ensures(Contract.Result<IQbservable<TResult>>() != null, null, "Contract.Result<IQbservable<TResult>>() != null");
			return null;
		}
	}
}